# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__docformat__ = 'restructuredtext en'
__all__ = []

from ... import formlib as layout
from ... import pilelib as stack
from ...gamelib import info as gi, game
from ...packlib import info as cs
from ...piles import hanafuda as hstack
from ...utillib.misc import kwdefault

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class Oonsoo(cs.Hanafuda_Deck, game.Game):
    """
    Arrange 1 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.Trusty12Layout
        - row [12 vore 2 row N, vert offset]
        - talon [1 NW]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.DealRowTalon

        Deal 1 card per `s.rows` on click. No redeal.

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 2 card. Build down in rank by same suit with trash cards swap
        except Willow. Play any. Base 1st rank.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d09, name='Oonsoo', category=cs.TYPE_HANAFUDA,
                    game_type=(GT.SPIDER | GT.POPULAR), decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='3.20')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.Trusty12Layout
    _talon_ = stack.DealRowTalon
    _row_ = Wrap(hstack.RankSS_RowStack, base_rank=cs.FIRST, strict=False)
    _reserves_ = None

    def _create_game(self, **kw):
        kwdefault(kw, texts=True, playcards=12, rows=12, npiles=6)
        return super(Oonsoo, self)._create_game(**kw)

    def _start(self):
        self._play_sound('deal')
        self.s['talon'].dealRow(flip=False)
        self.s['talon'].deal_cards()

    @property
    def is_complete(self):
        """
        Check `s.rows` has 4 cards each that are in `_build_sequence`.
        """
        return all(len(s.cards) == 4 and s._build_sequence(s.cards)
                   for s in self.s['rows'])


class OonsooToo(Oonsoo):
    """
    Arrange 1 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.Trusty12Layout
        - row [12 over 2 N, vert offset]
        - reserve [1 S talon, no offset]
        - talon [1 NW]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.DealRowTalon

        Deal 1 card per `s.rows` on click. No redeal.

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 2 card. Build down in rank by same suit with trash cards swap
        except Willow. Play any. Base 1st rank.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.ReserveStack

        Build any. Play top. Max 1 card.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d1e, name='Oonsoo Too', category=cs.TYPE_HANAFUDA,
                    game_type=GT.SPIDER, decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.50fc')
    __author__ = 'Mt. Hood Playing Card'
    __version__ = 7.70

    _reserves_ = stack.ReserveStack

    def _create_game(self, **kw):
        kw.setdefault('reserves', 1)
        super(OonsooToo, self)._create_game(**kw)


class OonsooStrict(OonsooToo):
    """
    Arrange 1 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.Trusty12Layout
        - row [12 horz N, vert offset]
        - reserve [2 vert S talon, no offset]
        - talon [1 NW]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.DealRowTalon

        Deal 1 card per `s.rows` on click. No redeal.

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 2 card. Build down in rank by same suit. Play any. Base 1st rank.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.ReserveStack

        Build any. Play top. Max 1 card.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d1f, name='Oonsoo Strict',
                    category=cs.TYPE_HANAFUDA, game_type=GT.SPIDER, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.50fc')
    __author__ = 'Mt. Hood Playing Card'
    __version__ = 7.70

    _row_ = Wrap(hstack.RankSS_RowStack, base_rank=cs.FIRST, strict=True)

    def _create_game(self, **kw):
        kw.setdefault('reserves', 2)
        super(OonsooToo, self)._create_game(**kw)


class OonsooOpen(Oonsoo):
    """
    Arrange 1 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.Trusty12Layout
        - row [12 over 2 row N, vert offset]
        - talon [1 NW]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.DealRowTalon

        Deal 1 card per `s.rows` on click. No redeal.

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 2 card. Build down in rank by same suit with trash cards swap
        except Willow. Play any.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d20, name='Oonsoo Open', category=cs.TYPE_HANAFUDA,
                    game_type=GT.SPIDER, decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.50fc')
    __author__ = 'Mt. Hood Playing Card'
    __version__ = 7.70

    _row_ = Wrap(hstack.RankSS_RowStack, strict=False)


class OonsooTimesTwo(OonsooToo):
    """
    Arrange 2 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.Trusty12Layout
        - row [24 over 2 row N, vert offset]
        - reserve [1 S talon, no offset]
        - talon [1 NW]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.DealRowTalon

        Deal 1 card per `s.rows` on click. No redeal.

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 2 card. Build down in rank by same suit with trash cards swap
        except Willow. Play any. Base 1st rank.

      _reserve_ : pysollib.stack.Stack
        .. pysollib.stack.ReserveStack

        Build any. Play top. Max 1 card.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d2b, name='Oonsoo ×2', category=cs.TYPE_HANAFUDA,
                    game_type=GT.SPIDER, decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.50fc', altnames=('Oonsoo (2 Decks)',))
    __author__ = 'Mt. Hood Playing Card'
    __version__ = 7.70

    def _create_game(self, **kw):
        kwdefault(kw, rows=24, npiles=12)
        super(OonsooToo, self)._create_game(**kw)


class HanafudaFourSeasons(cs.Hanafuda_Deck, game.Game):
    """
    Arrange 1 deck on _row_.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layout.CurdsWheyLayout
        - row [12 over 2 row N, vert offset]
        - talon [1 SE]

      _talon_ : pysollib.stack.Stack
        .. pysollib.stack.InitialDealTalon

      _row_ : pysollib.stack.Stack
        .. pysollib.stacks.hanufuda.RankSS_RowStack (base_rank=cs.FIRST,
          strict=False)

        Init 4 open card. Build down in rank by same suit. Play any. Base 1st
        rank. Max 8 card. Piles must be in suit order to succeed.

      _hint_ : pysollib.hint.AbstractHint
        .. pysollib.hint.DefaultHint
    """
    __info__ = dict(id=0x49d2a, name='Four Seasons (Hanafuda)',
                    category=cs.TYPE_HANAFUDA, game_type=(GT.SPIDER |
                    GT.OPEN), decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.50fc')
    __author__ = 'Mt. Hood Playing Card'
    __version__ = 7.70

    _layout_ = layout.CurdsWheyLayout
    _talon_ = stack.InitialDealTalon
    _row_ = Wrap(hstack.RankSS_RowStack, max_cards=8, max_accept=8,
                 base_rank=cs.FIRST)

    def _create_game(self, **kw):
        kwdefault(kw, rows=12, ncols=6, texts=False, playcards=10)
        return super(HanafudaFourSeasons, self)._create_game(**kw)

    def _start(self, rows=4, **kw):
        for i in range(rows - 1):
            self.s['talon'].dealRow(frames=0)
        self._play_sound('deal')
        self.s['talon'].dealRow()

    @property
    def is_complete(self):
        """
        Check `s.tableaux` has 4 cards each that are in `_build_sequence` and
        each suit is in order from W to E.
        """
        return all(len(r.cards) == 4 and r._build_sequence(r.cards) and
                   r.id == r.BASECARD['suit'] for r in self.s['rows'])


PROVIDES = [Oonsoo, OonsooToo, OonsooStrict, OonsooOpen, OonsooTimesTwo,
            HanafudaFourSeasons]